import axios, {AxiosError, AxiosRequestConfig, AxiosResponse} from "axios";
import {tokenName, whiteApiList} from "@/config/request-config.ts";
import {Modal, notification} from "antd";
import {getToken, updateToken} from "@/utils/Auth.ts";

/**
 * @author 橘柚
 * @Date 2023/11/13 19:34
 * @Description Axios 实例
 */

const instance = axios.create({
  baseURL: import.meta.env.VITE_APP_BASE_API || '/api',
  timeout: 5000
})

export interface ResponseBody<T = any> {
  code: number
  data?: T
  msg: string
}

instance.interceptors.request.use(config => {

    const token = getToken()

    const url = config.url
    // 判断请求的URL是否在白名单里面
    if ((!whiteApiList.includes(url as string)) && token) {
      config.headers.set(tokenName, token)
    }
    return config;
  }, ((error: AxiosError) => {
    console.log('@', error)
    return Promise.reject(error);
  })
)

instance.interceptors.response.use((response: AxiosResponse<ResponseBody, any>): ResponseBody<any> | Promise<any> | AxiosResponse | any => {

  // 未设置状态码则默认成功状态
  const code = response.data.code || 200;
  // 获取错误信息
  const msg: string = response.data.msg || '未知错误'

  if (code === 404) {

    notification.open({
      message: 'ERROR-' + code,
      description: msg,
      type: 'error'
    });

    return Promise.reject(new Error(msg));

  } else if (code === 401) {

    Modal.error({
      title: '登录信息异常！',
      content: '您的登录信息异常，请重新登录',
      onOk() {
        updateToken('')
        window.location.href = '/login'
      }
    });

    return Promise.reject(new Error(msg));
  } else if (code == 200) {
    return response.data
  } else {
    notification.open({
      message: 'ERROR-' + code,
      description: msg,
      type: 'error'
    });

    return Promise.reject(new Error(msg));
  }

}, (error: AxiosError) => {
  notification.open({
    message: 'Error:' + error.code,
    description: error.message,
    type: 'error'
  });
  return Promise.reject(error)
})
export default instance

export const sendGet = <R = any, P = any>(url: string, params?: P, config?: AxiosRequestConfig): Promise<ResponseBody<R>> => {
  return instance.request<ResponseBody<R>, ResponseBody<R>, P>({
    url,
    method: 'GET',
    params,
    ...config
  })
}

export const sendPost = <R = any, P = any>(url: string, data?: P, config?: AxiosRequestConfig): Promise<ResponseBody<R>> => {
  return instance.request<R, ResponseBody<R>>({
    url,
    method: 'POST',
    data,
    ...config,
  })
}

export const sendPut = <R = any, P = any>(url: string, data?: P, config?: AxiosRequestConfig): Promise<ResponseBody<R>> => {
  return instance.request<ResponseBody<R>, ResponseBody<R>, P>({
    url,
    method: 'PUT',
    data,
    ...config,
  })
}

export const sendDelete = <R = any, P = any>(url: string, data?: P, config?: AxiosRequestConfig): Promise<ResponseBody<R>> => {
  return instance.request<ResponseBody<R>, ResponseBody<R>, P>({
    url,
    method: 'DELETE',
    data,
    ...config,
  })
}
